package com.et114.components.acegi.acl.creator;

import org.acegisecurity.AccessDeniedException;
import org.acegisecurity.Authentication;
import org.acegisecurity.ConfigAttributeDefinition;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.acl.basic.AclObjectIdentity;
import org.acegisecurity.acl.basic.NamedEntityObjectIdentity;
import org.acegisecurity.acl.basic.SimpleAclEntry;
import org.springframework.dao.DataAccessException;
import org.springframework.util.Assert;

import com.et114.components.acegi.acl.AclUtils;
import com.et114.components.acegi.acl.domain.AclDomainAware;

import java.util.ArrayList;
import java.util.List;

/**
 *  * @author guanhw
 * 绠�鍗曠殑creator瀹炵幇锛岀粰鍚屼竴瑙掕壊鐨勪汉璧嬩簣鍙鏉冮檺锛屾湰浜虹鐞嗘潈闄愩��
 */
public class SimpleAclCreator extends AbstractBasicAclCreator {

    private Integer defaultRoleMask = new Integer ( SimpleAclEntry.READ );

    private Integer defaultCreatorMask = new Integer ( SimpleAclEntry.ADMINISTRATION ) ;

    protected Class processDomainObjectClass = AclDomainAware.class;

    protected Class processReturnedObjectClass = null;

    protected Class defaultAclObjectIdentityClass = NamedEntityObjectIdentity.class;

    public Integer getDefaultCreatorMask() {
        return defaultCreatorMask;
    }

    public void setDefaultCreatorMask(Integer defaultCreatorMask) {
        this.defaultCreatorMask = defaultCreatorMask;
    }

    public Integer getDefaultRoleMask() {
        return defaultRoleMask;
    }

    public void setDefaultRoleMask(Integer defaultRoleMask) {
        this.defaultRoleMask = defaultRoleMask;
    }

    public void creat(Authentication authentication, Object domainInstance,
                      ConfigAttributeDefinition config, Object returnedObject)
            throws AccessDeniedException {

        SimpleAclEntry[] acls = getEntry(authentication, domainInstance,
                returnedObject);

        try {
            for (int i = 0; i < acls.length; i++) {
                aclDAO.create(acls[i]);
            }
        } catch (DataAccessException e) {
            logger.warn("parent not found");
        }
    }

    protected AclObjectIdentity getParentAclIdentity(Object domainInstance) {
        return null;
    }

    protected SimpleAclEntry[] getEntry(Authentication authentication,
                                        Object domainInstance, Object returnedObject) {
        AclObjectIdentity aclIdentity = AclUtils.obtainIdentity( domainInstance , defaultAclObjectIdentityClass);
        Assert.notNull( aclIdentity , "domainInstance is not supported by this creator" );

        AclObjectIdentity parentAclIdentity = getParentAclIdentity(domainInstance);
        GrantedAuthority[] authoritys = authentication.getAuthorities();
        List list = new ArrayList();

        for (int i = 0; i < authoritys.length; i++) {
            GrantedAuthority auth = authoritys[i];
            if (auth.getAuthority().startsWith("ROLE_")) {
                SimpleAclEntry aclEntry = new SimpleAclEntry(auth
                        .getAuthority(), aclIdentity, parentAclIdentity,
                        defaultRoleMask.intValue());
                list.add(aclEntry);
            }
        }

        if (authentication.getPrincipal() != null) {
            SimpleAclEntry aclEntry = new SimpleAclEntry(authentication
                    .getPrincipal().toString(), aclIdentity, parentAclIdentity,
                    defaultCreatorMask.intValue());
            list.add(aclEntry);
        }
        return null;
        //return list.toArray(	new SimpleAclEntry[ list.size() ]	);
    }

    public boolean supports(Object domainObject, Object returnedObject) {
        return ((domainObject == null && processDomainObjectClass == null) || this.processDomainObjectClass
                .isAssignableFrom(domainObject.getClass()))
                && ((returnedObject == null && processReturnedObjectClass == null) || this.processReturnedObjectClass
                .isAssignableFrom(returnedObject.getClass()));
    }
}
